package business_logic.game_elements;


import java.util.Collection;
import java.util.EnumSet;

import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import business_logic.GameElement;
import business_logic.Tile;
import business_logic.view.GameViewIdentifier;


import model.collisions.CollisionCategory;
import model.elements.Element2D;
import model.elements.Wall;
import model.elements.attributes.Coordinate2D;
import model.elements.commands.ElementCommandFactory;
import model.exceptions.CommandFactoryIsNotReady;
import model.exceptions.ModelExceptions;

public final class BloqueLadrillos extends Wall implements GameElement,Dropper
{
	
	private static final int BloqueLadrillosHitPoints = 5;
	private static final CollisionCategory BloqueLadrillosCollisionCategory= CollisionCategory.C_T1_WALL;
	
	/*
    private static final Collection<GameViewIdentifier> m_viewIdentifiers = 
            EnumSet.of(GameViewIdentifier.SPRITE_BLOQUE_DE_LADRILLOS); 
    */
	
    private static final Collection<GameViewIdentifier> m_viewIdentifiers = 
            EnumSet.of
            (
                GameViewIdentifier.SPRITE_BLOQUE_DE_LADRILLOS,
                GameViewIdentifier.CHEAT_DROP
            );
    
    private GameElement m_drop;
    
    public BloqueLadrillos(Coordinate2D position) throws ModelExceptions
    {
        super(position, BloqueLadrillosCollisionCategory, BloqueLadrillosHitPoints);
    }
    
    /*
    public BloqueLadrillos(Coordinate2D position, Element2D drop) throws ModelExceptions
    {
        super(position, BloqueLadrillosCollisionCategory, BloqueLadrillosHitPoints);
        m_drop = drop;
    }
    */
    
    public Collection<GameViewIdentifier> getViewIdentifiers()
    {
        return m_viewIdentifiers;
    }
    
    @Override
    public void vivir()
    {
        try {
			this.update();
		} catch (ModelExceptions e) {
			e.printStackTrace();
		}
    }
    
    @Override
    public int getX()
    {
        return Tile.pixelToTile( m_currentPosition.getRealX() );
    }
    
    @Override
    public int getY()
    {
        return Tile.pixelToTile( m_currentPosition.getRealY() );
    }
    
    public void setDrop(GameElement drop)
    {
    	m_drop = drop;
    }
    
    public boolean hasDrop()
    {
    	return m_drop != null;
    }

	public GameElement getDrop()
	{
		return m_drop;
	}
    
    @Override
    public void onDeath() throws CommandFactoryIsNotReady, ModelExceptions
    {
    	if(hasDrop())
    		ElementCommandFactory.getElementDrop((Element2D)getDrop()).execute(this);
    	kill();
    }

    private static final long m_serialVersionUID = 1L;
    
    @Override
    public Element save()
    {
        Element elem = DocumentHelper.createElement( this.getClass().getName() );
        elem.addAttribute( "serialVersion", m_serialVersionUID+"" );
        elem.addAttribute( "x", Math.floor( this.getPosition().getRealX() ) +"" );
        elem.addAttribute( "y", Math.floor( this.getPosition().getRealY() ) +"" );
        //elem.addAttribute( "lives", this.m_lives.getValue()+"" );
        if ( this.getDrop() == null )
            elem.addAttribute( "drop", "null" );
        else
            elem.addAttribute( "drop", this.getDrop().getClass().getName()+"" );
        
        return elem;
    }
    
    public BloqueLadrillos( Element elem ) throws ModelExceptions
    {
        super
        (
            new Coordinate2D
            (
                Double.parseDouble(elem.attributeValue("x")),
                Double.parseDouble(elem.attributeValue("y"))
            ),
            BloqueLadrillosCollisionCategory,
            //Integer.parseInt(elem.attributeValue("lives"))
            BloqueLadrillosHitPoints
        );
        
        try
        {
            String dropClass = elem.attributeValue("drop");
            @SuppressWarnings("unchecked")
            Class<? extends Element2D> elemClass = (Class<? extends Element2D>) Class.forName(dropClass);
            Element2D drop;
            drop = elemClass.getDeclaredConstructor(Coordinate2D.class).newInstance( new Coordinate2D() );
            this.setDrop( (GameElement) drop);
        }
        catch (Exception e)
        {    
        }
    }
    
}
